﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

using LowLevelGraphics;
using LowLevelGraphics.Histograms;

namespace ImageRecognition2.Forms
{
    /// <summary>
    /// Profile Form
    /// </summary>
    public partial class FormProfile : Form
    {
        public event EventHandler GetPicture = null;
        private UnsafeBitmap m_Bitmap = null;
        private Histogram m_Histogram = null;

        private int nX1 = -1;
        private int nX2 = -1;
        private int nY1 = -1;
        private int nY2 = -1;

        protected delegate UnsafeBitmap AverageValue(Bitmap _bitmap);
        protected PROCESSING_MODE M_PROCESSINGMODE = PROCESSING_MODE.None;
        protected Dictionary<PROCESSING_MODE, AverageValue> m_aHistogramMode = new Dictionary<PROCESSING_MODE, AverageValue>();
        /// <summary>
        /// This constructor shouldn't be used
        /// </summary>
        public FormProfile()
        {
            InitializeComponent();

            this.pictureBoxProfile.BackgroundImageLayout = ImageLayout.Zoom;

            foreach (PROCESSING_MODE mode in Enum.GetValues(typeof(PROCESSING_MODE)))
            {
                this.comboBox1.Items.Add(mode);
            }

            //m_aHistogramMode.Add(PROCESSING_MODE.Hue, new AverageValue(LowLevelGraphics.Histograms.Histogram.AverageHue));
            //m_aHistogramMode.Add(PROCESSING_MODE.Brightness,  new AverageValue(Histogram.AverageBrightness));
            //m_aHistogramMode.Add(PROCESSING_MODE.Luminance, new AverageValue(LowLevelGraphics.Histograms.Histogram.AverageLuminance));
            //m_aHistogramMode.Add(PROCESSING_MODE.Saturation,  new AverageValue(LowLevelGraphics.Histograms.Histogram.AverageSaturation));

            this.comboBox1.SelectedIndexChanged += new EventHandler(comboBox1_SelectedIndexChanged);
        }

        /// <summary>
        /// Initializes a new instance of the <see cref="FormProfile"/> class.
        /// </summary>
        /// <param name="_bitmap">The _bitmap.</param>
        public FormProfile(UnsafeBitmap _bitmap)
            : this(_bitmap, PROCESSING_MODE.None)
        {
        }

        /// <summary>
        /// Initializes a new instance of the <see cref="FormProfile"/> class.
        /// </summary>
        /// <param name="_bitmap">The _bitmap.</param>
        /// <param name="_MODE">The _ MODE.</param>
        public FormProfile(UnsafeBitmap _bitmap, PROCESSING_MODE _MODE)
            : this()
        {
            m_Bitmap = _bitmap;
            m_Histogram = new Histogram(10, m_Bitmap, Rectangle.FromLTRB(nX1, nY1, nX2, nY2), 1, 1);
            tbX1.Text = "0";
            tbX2.Text = m_Bitmap.Width.ToString();
            tbY1.Text = "0";
            tbY2.Text = m_Bitmap.Height.ToString();
            int nINdex = comboBox1.FindString(_MODE.ToString());
            this.comboBox1.SelectedIndex = nINdex;
        }

        /// <summary>
        /// Handles the SelectedIndexChanged event of the comboBox1 control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param>
        private void comboBox1_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (m_Bitmap == null) return;
            if (!chkbActualizeImmediately.Checked) return;
            ActualizeDisplayData();
        }

        /// <summary>
        /// Actualizes Display data
        /// </summary>
        private void ActualizeDisplayData()
        {
            nX1 = Convert.ToInt32(tbX1.Text);
            nX2 = Convert.ToInt32(tbX2.Text);
            nY1 = Convert.ToInt32(tbY1.Text);
            nY2 = Convert.ToInt32(tbY2.Text);
            M_PROCESSINGMODE = (PROCESSING_MODE)comboBox1.SelectedItem;
            m_Bitmap.UnlockImage();
            m_Bitmap.LockImage();
            m_Histogram = new Histogram(10, m_Bitmap, Rectangle.FromLTRB(nX1, nY1, nX2, nY2), 1, 1);
            m_Bitmap.Dispose();
            Bitmap bitmap = CreateBitmap();

            this.pictureBoxProfile.BackgroundImage = bitmap;
        }

        /// <summary>
        /// Raises the <see cref="E:System.Windows.Forms.Form.Closed"/> event.
        /// </summary>
        /// <param name="e">The <see cref="T:System.EventArgs"/> that contains the event data.</param>
        protected override void OnClosed(EventArgs e)
        {
            base.OnClosed(e);
        }

        /// <summary>
        /// return or set bitmap
        /// </summary>
        /// <value>The bitmap.</value>
        public Bitmap Bitmap
        {
            get { return (Bitmap)this.pictureBoxProfile.BackgroundImage; }
            set { this.pictureBoxProfile.BackgroundImage = value; }
        }

        /// <summary>
        /// Handles the Click event of the takePicToolStripMenuItem control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param>
        private void takePicToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if (GetPicture != null)
            {
                GetPicture(this, e);
            }
            this.Close();
        }

        /// <summary>
        /// Create bitmap
        /// </summary>
        public Bitmap CreateBitmap()
        {
            int x = 0;
            int y = 0;

            UnsafeBitmap bitmap = m_Bitmap;

            Bitmap bmp2 = new Bitmap(bitmap.Width, bitmap.Height);
            Graphics g = Graphics.FromImage(bmp2);

            bitmap.UnlockImage();
            g.FillRectangle(Brushes.Black, new Rectangle(0, 0, bmp2.Width, bmp2.Height));
            bitmap.LockImage();

            int nWidth = bitmap.Width;
            int nHeight = bitmap.Height;

            ColorCalculation calculation = Definitions.ColorCalculationDictionaryProcessingMode[M_PROCESSINGMODE];
            for (x = 0; x < nWidth; x++)
            {
                List<float> aValue = new List<float>();
                for (y = 0; y < nHeight; y++)
                {
                    aValue.Add(calculation(bitmap.GetPixel(x, y)));
                }

                float fValue = ColorFunctions.AverageBrightness(aValue);
                aValue.Clear();
                bitmap.UnlockImage();
                g.DrawLine(Pens.Blue, x, bmp2.Height, x, bmp2.Height - fValue * 500);
                bitmap.LockImage();
            }
            bitmap.Dispose();
            return bmp2;
        }

        /// <summary>
        /// Actualize display data
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param>
        private void cbActualize_Click(object sender, EventArgs e)
        {
            ActualizeDisplayData();
        }
    }
}
